package org.watchrecords.elements;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

import org.apache.commons.lang.StringUtils;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.watchrecords.dbo.Identifiable;
import org.watchrecords.util.ObjectHelper;

import com.google.inject.Inject;
import com.google.inject.Provider;

public class BasicForm<T extends Identifiable> extends Form<T> {
    /**
     * 
     */
    private static final long serialVersionUID = 647957903122096968L;
    @Inject
    private static Provider<EntityManager> emProvider; 
    
    protected void doSubmit() {}
    
    @Override
    protected void onSubmit() {
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        
        Set<ConstraintViolation<T>> violations = validator.validate(getModelObject());
        
        for (ConstraintViolation<T> violation: violations) {
            Component component = ObjectHelper.nvl(get(violation.getPropertyPath()), this);
            component.error(StringUtils.defaultString(violation.getInterpolatedMessage()));
        }
        
        if (violations.isEmpty()) {
            doSubmit();
        }
    }

    public BasicForm(String id, T object) {
        super(id, new CompoundPropertyModel<T>(new LoadableDetachableModel<T>(object) {
            private Class<T> klass;
            private Integer id;

            /**
             * 
             */
            private static final long serialVersionUID = -2958303668483951237L;

            @Override
            protected T load() {
                try {
                    return id == null ? klass.newInstance() : emProvider.get().find(klass, id);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            @SuppressWarnings("unchecked")
            @Override
            public void detach() {
                T object = getObject();
                klass = (Class<T>) object.getClass();
                id = object.getId();
                super.detach();
            }
            
        }));
    }
}
